/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package gpsserver;

/*
 * To change this template, choose Tools | Templates and open the template in
 * the editor.
 */
import java.io.IOException;
import java.net.Socket;
import java.net.SocketException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;
import system.Exc;
import system.Persistencia;

/**
 *
 * @author DELL
 */
public class ServerThread extends Thread {

    private Socket socket = null;
    private String sql;
    private Persistencia persistencia = new Persistencia();
    int dataBuffer, id_usuario;
    String[] dato;
    StringBuilder lectura = null;
    String imei, trama;
    Double latitud, longitud;
    Date fecha_y_hora;
    private boolean terminar = false;
    int i = 0;

    ServerThread(Socket socket) throws SocketException {
        state("Creando hilo....");
        this.socket = socket;
    }

    public void setTerminar(boolean terminar) {
        this.terminar = terminar;
    }

    @Override
    public void run() {
        try {
            while (!terminar) {
                lectura = new StringBuilder();
                while ((dataBuffer = socket.getInputStream().read()) != 59) {
                    lectura.append((char) dataBuffer);
                    if (lectura.indexOf("GPRMC") != -1) {
                        if (lectura.indexOf("imei:") != -1) {
                            String g_try;
                            g_try = lectura.substring(lectura.lastIndexOf(":") + 1, lectura.length());
                            if (g_try.length() == 15) {
                                break;
                            }
                        }
                    }
                }
                if (lectura.indexOf("imei") != -1) {
                    formatearTrama(lectura);
                    loadData();
                    if (dato.length >= 12) {
                        if (lectura.indexOf("tracker") == -1) {
                            getData_Cobal();
                        } else if (lectura.indexOf("GPRMC") == -1) {
                            getData_Xexun();
                        }
                        insertarBD();
                        i++;
                        if (i == 2) {
                            socket.close();
                            setTerminar(true);
                        }
                    } else if (dato.length >= 1 & dato.length <= 7) {
                        state("no gps signal format...");
                    } else {
                        state("No GPS LOAD");
                    }
                }
            }
        } catch (IOException ex) {
            Logger.getLogger(ServerThread.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ParseException ex) {
            Logger.getLogger(ServerThread.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exc ex) {
            Logger.getLogger(ServerThread.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SQLException ex) {
            Logger.getLogger(ServerThread.class.getName()).log(Level.SEVERE, null, ex);
        } catch (Exception ex) {
            Logger.getLogger(ServerThread.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void formatearTrama(StringBuilder lectura) {
        trama = lectura.toString().replaceAll(",,", ",nulo,");
    }

    private void loadData() {
        dato = trama.split(",");
    }

    private void getData_Cobal() throws ParseException {
        imei = dato[0].substring(dato[0].lastIndexOf(":") + 1, dato[0].length());
        latitud = convertirCoordenadas(dato[7], dato[8]);
        longitud = convertirCoordenadas(dato[9], dato[10]);
        fecha_y_hora = ConvertirFecha(dato[2]);
    }

    private void getData_Xexun() throws ParseException {
       imei = dato[16].substring(dato[16].lastIndexOf(":") + 1, dato[16].length());
        latitud = convertirCoordenadas(dato[5], dato[6]);
        longitud = convertirCoordenadas(dato[7], dato[8]);
        fecha_y_hora = ConvertirFecha(dato[1], dato[3]);
    }

    public Double convertirCoordenadas(String coordenada, String direccion) {
        String minutos, grados;
        double posicion;
        String[] temp = new String[2];
        int i = 0;
        StringTokenizer tokens = new StringTokenizer(coordenada, ".");
        while (tokens.hasMoreTokens()) {
            temp[i] = tokens.nextToken();
            i++;
        }
        grados = temp[0].substring(1, temp[0].length() - 2);
        minutos = temp[0].substring(temp[0].length() - 2);
        posicion = Integer.parseInt(grados) + ((Double.parseDouble(minutos.concat(".").concat(temp[1]))) / 60);
        if ("S".equals(direccion) || "W".equals(direccion)) {
            posicion = posicion * (-1);
        }
        return posicion;
    }

    public Date ConvertirFecha(String fechasyhoras) throws ParseException {
        String hora, fecha;
        fecha = fechasyhoras.substring(0, 6);
        hora = fechasyhoras.substring(6, fechasyhoras.length());
        Date convertedDate;
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
        fecha = FormatearFecha(fecha);
        hora = FormatearHora(hora);
        convertedDate = dateFormat.parse(fecha + " " + hora);
        return convertedDate;
    }

    public Date ConvertirFecha(String fechas, String horas) throws ParseException {
        String dateString, timeString;
        int hora = Integer.parseInt(horas.substring(0, horas.indexOf(".")));
        Date convertedDate;
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yy HH:mm:ss");
        if (hora < 50001) {
            hora = hora - 50000;
            fechas = Integer.toString(Integer.parseInt(fechas) - 10000);
            dateString = FormatearFechaX(fechas);
            timeString = FormatearHoraX(Integer.toString(hora));
            convertedDate = dateFormat.parse(dateString + " " + timeString);
        } else {
            hora = hora - 50000;
            dateString = FormatearFechaX(fechas);
            timeString = FormatearHoraX(Integer.toString(hora));
            convertedDate = dateFormat.parse(dateString + " " + timeString);
        }
        return convertedDate;
    }

    public String FormatearFecha(String fechas) {
        String date;
        date = fechas.substring(4, 6).concat("/").concat(fechas.substring(2, 4)).concat("/").concat(fechas.substring(0, 2));
        return date;
    }

    public String FormatearHora(String fechas) {
        String hora;
        hora = fechas.substring(0, 2).concat(":").concat(fechas.substring(2, 4).concat(":").concat(dato[5].substring(4, 6)));
        return hora;
    }

    
    public String FormatearFechaX(String fechas) {
        String date;
        date = fechas.substring(0, 2).concat("/").concat(fechas.substring(2, 4)).concat("/").concat(fechas.substring(4, 6));
        return date;
    }

    public String FormatearHoraX(String fechas) {
        String date;
        date = fechas.substring(0, 2).concat(":").concat(fechas.substring(2, 4)).concat(":").concat(fechas.substring(4, 6));
        return date;
    }
    
    public void insertarBD() throws Exc, SQLException, Exception {
        boolean flag = true;
        sql = "SELECT ug.id_usuario AS id_usuario FROM usuario_gps ug "
                + "INNER JOIN gps g ON (ug.id_gps = g.id) "
                + "WHERE g.imei = '" + imei + "'";
        ResultSet rsts = persistencia.executeRsts(sql);
        while (rsts.next()) {
            id_usuario = rsts.getInt("id_usuario");
        }
        rsts.close();
        sql = "SELECT * FROM gps_tramas WHERE imei = '" + imei + "' "
                + "AND coordenadas = ST_GeomFromText('POINT(" + latitud + " " + longitud + ")',4326) "
                + "AND fecha = '" + fecha_y_hora + "' AND id_usuario = " + id_usuario;
        rsts = persistencia.executeRsts(sql);
        if (rsts.getRow() == 0) {
            sql = "INSERT INTO \"gps_tramas\"( imei, coordenadas , fecha, trama, id_usuario) " + "VALUES ('"
                    + imei + "',ST_GeomFromText('POINT(" + latitud + " " + longitud + ")',4326),'" + fecha_y_hora + "','" + trama + "'," + id_usuario + ")";
            persistencia.executeUpdate(sql);
        }
        rsts.close();
    }

    private void state(String mensaje) {
        System.out.println(mensaje);
    }
}
